package com.easyjava.builder;

import com.easyjava.bean.Constants;
import com.easyjava.bean.FieldInfo;
import com.easyjava.bean.TableInfo;
import com.easyjava.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * @projectName: work-space
 * @author: Li
 * @description:
 */

public class BuildService {
    private static final Logger logger = LoggerFactory.getLogger(BuildService.class);

    public static void execute(TableInfo tableInfo) {
        File folder = new File(Constants.PATH_SERVICE);
        if (!folder.exists()) {
            folder.mkdirs();
        }

        String className = tableInfo.getBeanName() + "Service";
        File poFile = new File(folder, className + ".java");

        OutputStream os = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            os = new FileOutputStream(poFile);
            osw = new OutputStreamWriter(os, "UTF-8");
            bw = new BufferedWriter(osw);
            bw.write("package " + Constants.PACKAGE_SERVICE + ";");
            bw.newLine();
            bw.newLine();

            bw.write("import java.util.List;");
            bw.newLine();
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + ";");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanQueryName() + ";");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_VO + ".PaginationResultVo;");


            bw.newLine();
            bw.newLine();
            BuildComment.createClassComment(bw, tableInfo.getTableName() + " Service");
            bw.newLine();
            bw.write("public interface " + className + " {");
            bw.newLine();

            BuildComment.createFieldComment(bw, "根据条件查询列表");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tList<" + tableInfo.getBeanName() + "> findListByParam(String tableName, " + tableInfo.getBeanQueryName() + " query);");
            } else {
                bw.write("\tList<" + tableInfo.getBeanName() + "> findListByParam(" + tableInfo.getBeanQueryName() + " query);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "根据条件查询数量");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tInteger findCountByParam(String tableName, " + tableInfo.getBeanQueryName() + " query);");
            } else {
                bw.write("\tInteger findCountByParam(" + tableInfo.getBeanQueryName() + " query);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "分页查询");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tPaginationResultVo<" + tableInfo.getBeanName() + "> findListByPage(String tableName, " + tableInfo.getBeanQueryName() + " query);");
            } else {
                bw.write("\tPaginationResultVo<" + tableInfo.getBeanName() + "> findListByPage(" + tableInfo.getBeanQueryName() + " query);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "新增");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tInteger add(String tableName, " + tableInfo.getBeanName() + " bean);");
            } else {
                bw.write("\tInteger add(" + tableInfo.getBeanName() + " bean);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "批量新增");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tInteger addBatch(String tableName, List<" + tableInfo.getBeanName() + "> listBean);");
            } else {
                bw.write("\tInteger addBatch(List<" + tableInfo.getBeanName() + "> listBean);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "批量新增/更新");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tInteger addOrUpdateBatch(String tableName, List<" + tableInfo.getBeanName() + "> listBean);");
            } else {
                bw.write("\tInteger addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> listBean);");
            }
            bw.newLine();
            bw.newLine();

            Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
            for (Map.Entry<String, List<FieldInfo>> entry : keyIndexMap.entrySet()) {
                List<FieldInfo> keyFieldInfoList = entry.getValue();
                int index = 0;
                StringBuilder methodName = new StringBuilder();
                StringBuilder paramsName = new StringBuilder();
                if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                    paramsName.append("String tableName, ");
                }
                for (FieldInfo fieldInfo : keyFieldInfoList) {
                    index++;
                    methodName.append(StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()));
                    if (index < keyFieldInfoList.size()) {
                        methodName.append("And");
                    }
                    paramsName.append(fieldInfo.getJavaType() + " " + fieldInfo.getPropertyName());
                    if (index < keyFieldInfoList.size()) {
                        paramsName.append(", ");
                    }
                }
                BuildComment.createFieldComment(bw, "根据" + methodName + "查询");
                bw.newLine();
                bw.write("\t" + tableInfo.getBeanName() + " get" + tableInfo.getBeanName() + "By" + methodName + "(" + paramsName + "); ");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw, "根据" + methodName + "更新");
                bw.newLine();
                bw.write("\tInteger update" + tableInfo.getBeanName() + "By" + methodName + "(" + tableInfo.getBeanName() + " bean, " + paramsName + "); ");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw, "根据" + methodName + "删除");
                bw.newLine();
                bw.write("\tInteger delete" + tableInfo.getBeanName() + "By" + methodName + "(" + paramsName + "); ");
                bw.newLine();
                bw.newLine();
            }

            BuildComment.createFieldComment(bw, "根据条件更新");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tvoid updateByQuery(String tableName, " + tableInfo.getBeanName() + " bean , " + tableInfo.getBeanQueryName() + " query);");
            } else {
                bw.write("\tvoid updateByQuery(" + tableInfo.getBeanName() + " bean , " + tableInfo.getBeanQueryName() + " query);");
            }
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw, "根据条件删除");
            bw.newLine();
            if (tableInfo.getTableName().equals(Constants.SPLIT_TABLE_NAME)) {
                bw.write("\tvoid deleteByQuery(String tableName, " + tableInfo.getBeanQueryName() + " query);");
            } else {
                bw.write("\tvoid deleteByQuery(" + tableInfo.getBeanQueryName() + " query);");
            }
            bw.newLine();
            bw.newLine();

            bw.write("}");
            bw.flush();

        } catch (Exception e) {
            logger.error("生成Service文件失败", e);
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (osw != null) {
                try {
                    osw.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
